package com.pn.config;

import cn.hutool.core.io.FileUtil;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;

import java.io.IOException;
import java.nio.charset.Charset;

/*
  资源服务器的配置类 --- 主要是使用公钥解析jwt token:
 */
//标记为资源服务器 -- 所有的业务模块通过引入公共模块的资源服务器配置类进而引入到该注解,就无需标记了
@EnableResourceServer
//开启方法级别的授权
@EnableGlobalMethodSecurity(prePostEnabled = true)
@Configuration
public class ResourceConfig extends ResourceServerConfigurerAdapter {

    /*
      1.配置TokenStore的bean对象 -- 实现类JwtTokenStore -- 告诉资源服务器解析jwt token
     */

    //配置jwt token转换器
    @Bean
    public JwtAccessTokenConverter jwtAccessTokenConverter(){
        //创建jwt token转换器
        JwtAccessTokenConverter jwtAccessTokenConverter = new JwtAccessTokenConverter();
        //给jwt token转换器设置公钥
        ClassPathResource resource = new ClassPathResource("publicKey.txt");
        String publicKey = "";
        try {
            publicKey = FileUtil.readString(resource.getFile(), Charset.defaultCharset());
        } catch (IOException e) {
            e.printStackTrace();
        }
        jwtAccessTokenConverter.setVerifierKey(publicKey);
        //返回jwt token转换器
        return jwtAccessTokenConverter;
    }

    @Bean
    public TokenStore tokenStore(){
        return new JwtTokenStore(jwtAccessTokenConverter());
    }

    /*
      2.向资源服务器暴露资源 -- 暴露TokenStore -- 实现类JwtTokenStore -- 告诉资源服务器解析jwt token
     */
    @Override
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
        resources.tokenStore(tokenStore());
    }

    /*
     3.请求配置:
     */
    @Override
    public void configure(HttpSecurity http) throws Exception {
        //取消请求跨站跨域的检查
        http.cors().disable();
        http.csrf().disable();

        //对actuator暴露的所有监控端点(url接口)直接放行
        http.authorizeRequests().antMatchers("/actuator/**").permitAll();

        //其它请求都是必须登录后才可以访问
        http.authorizeRequests().anyRequest().authenticated();
    }
}
